﻿using System;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using SqlSugar;
using NetMicro.Cache;
using NetMicro.Core.Extensions;
using NetMicro.Domains.Attributes;

namespace NetMicro.Domains.Strategy
{
    /// <summary>
    /// 分表实现
    /// </summary>
    public class DefaultTableFactory : ISqlTableFactory
    {
        private readonly IInMemoryCache _memoryCache;
        public DefaultTableFactory(IInMemoryCache memoryCache)
        {
            _memoryCache = memoryCache;
        }


        /// <summary>
        /// 获取自定义分表表名
        /// </summary>
        /// <param name="type"></param>
        /// <param name="subTableValue"></param>
        /// <returns></returns>
        public string GetTableName(SqlSugarClient db, Type type, object subTableValue = null)
        {
            string tableNameCacheKey = $"reflect_submeter_name:{type.Name}:{subTableValue}";
            string tableName = _memoryCache.Get<string>(tableNameCacheKey);
            if (!string.IsNullOrWhiteSpace(tableName))
                return tableName;
            tableName = TableName(type);
            PropertyInfo[] array = type.GetProperties();
            for (int i = 0; i < array.Length; i++)
            {
                PropertyInfo item = array[i];
                SuffixSubmeterAttribute submeterAttr = item.GetAttribute<SuffixSubmeterAttribute>();
                if (submeterAttr != null)
                {
                    tableName = new DefaultSuffixTableStrategy().ConvertToTable(subTableValue, tableName, submeterAttr);
                    break;
                }
                HashSubmeterAttribute submeterHashAttr = item.GetAttribute<HashSubmeterAttribute>();
                if (submeterHashAttr != null)
                {
                    tableName = new DefaultHashTableStrategy().ConvertToTable(subTableValue, tableName, submeterHashAttr);
                    break;
                }
            }
            if (!db.DbMaintenance.IsAnyTable(tableName))
            {
                db.MappingTables.Add(type.Name, tableName);
                db.CodeFirst.InitTables(type);
            }
            _memoryCache.Set(tableNameCacheKey, tableName);
            return tableName;
        }

        /// <summary>
        /// 表名
        /// </summary>
        protected virtual string TableName(Type type)
        {
            string cacheKey = $"reflect_conn:{type.Name}";
            string tableName = _memoryCache.Get(cacheKey);
            if (!string.IsNullOrWhiteSpace(tableName))
                return tableName;
            SugarTable tableAttr = (SugarTable)Attribute.GetCustomAttribute(type, typeof(SugarTable));
            if (tableAttr != null)
            {
                tableName = tableAttr.TableName;
            }
            else
            {
                tableName = type.Name.ToSnakeCase().Replace("_entity", "");
            }
            _memoryCache.Set(cacheKey, tableName);
            return tableName;
        }

    }
}
